{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n",
    "    <dl class=\"dl-horizontal\">\n",
    "      <dt>Title</dt> <dd> PolyEdit</dd>\n",
    "      <dt>Description</dt> <dd>A linked streams example demonstrating how to use the PolyEdit stream.</dd>\n",
    "      <dt>Backends</dt> <dd> Bokeh</dd>\n",
    "      <dt>Tags</dt> <dd> streams, linked, position, interactive</dd>\n",
    "    </dl>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "from holoviews import opts, streams\n",
    "\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``PolyEdit`` stream adds a bokeh tool to the source plot, which allows drawing, dragging and deleting vertices on polygons and making the drawn data available to Python. The tool supports the following actions:\n",
    "\n",
    "**Show vertices**\n",
    "\n",
    "    Double tap an existing patch or multi-line\n",
    "\n",
    "**Add vertex**\n",
    "\n",
    "    Double tap an existing vertex to select it, the tool will draw the next point, to add it tap in a new location.\n",
    "    To finish editing and add a point double tap otherwise press the ESC key to cancel.\n",
    "\n",
    "**Move vertex**\n",
    "\n",
    "    Drag an existing vertex and let go of the mouse button to release it.\n",
    "\n",
    "**Delete vertex**\n",
    "\n",
    "    After selecting one or more vertices press BACKSPACE while the mouse cursor is within the plot area.\n",
    "    \n",
    "As a simple example we will draw a number of boxes and ellipses by displaying them using a ``Polygons`` element and then link that element to two ``PolyEdit`` streams. Enabling the ``shared`` option allows editing multiple ``Polygons``/``Paths`` with the same tool.  You may also supply a ``vertex_style`` dictionary defining the visual attributes of the vertices once you double tapped a polygon:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(42)\n",
    "polys = hv.Polygons([hv.Box(*i, spec=np.random.rand()/3)\n",
    "                     for i in np.random.rand(10, 2)])\n",
    "ovals = hv.Polygons([hv.Ellipse(*i, spec=np.random.rand()/3)\n",
    "                     for i in np.random.rand(10, 2)])\n",
    "poly_edit = streams.PolyEdit(source=polys, vertex_style={'color': 'red'}, shared=True)\n",
    "poly_edit2 = streams.PolyEdit(source=ovals, shared=True)\n",
    "\n",
    "(polys * ovals).opts(\n",
    "    opts.Polygons(active_tools=['poly_edit'], fill_alpha=0.4, height=400, width=400))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center><img src=\"https://assets.holoviews.org/gifs/examples/streams/bokeh/poly_edit.gif\" width=400></center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Whenever the data source is edited the data is synced with Python, both in the notebook and when deployed on the bokeh server. The data is made available as a dictionary of columns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "poly_edit.data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively we can use the ``element`` property to get an Element containing the returned data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "poly_edit.element"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
